package hasthi.tools.analyze;

import hasthi.common.HasthiException;
import hasthi.common.XmlBeanUtils;
import hasthi.common.HasthiException.FaultCode;
import hasthi.test.FooDocument;
import hasthi.test.FooResponseDocument;

import java.util.concurrent.Semaphore;

import org.apache.xmlbeans.XmlObject;

public class ClientSet {
    private int clientCount;
    private int requestCountPerClient;
    private XmlObject message;
    private String serviceUrl;
    private Semaphore rendezvous = new Semaphore(0,true);
    private String name;
    private PerfClient.PerfResponseVerifier perfResponseVerifier;
    private long endTime;
    
    public ClientSet(String name,int clientCount, int requestCountPerClient, XmlObject message,String serviceUrl,PerfClient.PerfResponseVerifier perfResponseVerifier) {
        this.clientCount = clientCount;
        this.requestCountPerClient = requestCountPerClient;
        this.message = message;
        this.serviceUrl = serviceUrl;
        this.name = name;
        this.perfResponseVerifier = perfResponseVerifier;
    }
    
    public void runTests() throws HasthiException{
        try {
            PerfClient[] perfClients = new PerfClient[clientCount];
            for (int i = 0; i < clientCount ; i++) {
                perfClients[i] = new PerfClient(name+"[" +i + "]",serviceUrl,
                        requestCountPerClient,100, perfResponseVerifier,message);
                perfClients[i].setTestEndTime(endTime);
                RunnableWrapper wrapper = new RunnableWrapper(perfClients[i]);
                Thread t = new Thread(wrapper);
                t.setDaemon(true);
                t.start();
            }
            
            rendezvous.acquire(clientCount);
            DataSetBag dataSet = new DataSetBag(name);
            
            for (int i = 0; i < clientCount ; i++) {
                dataSet.addData(perfClients[i].getDataCollector());
            }
            dataSet.sendSummery();
            
        } catch (InterruptedException e) {
            throw new HasthiException(e, FaultCode.LocalError);
        }
        
    }
    
   public class RunnableWrapper implements Runnable{
       private Runnable runnable;
       private RunnableWrapper(Runnable runnable){
           this.runnable = runnable;
       }
    public void run() {
        try {
            runnable.run();
        }finally {
            rendezvous.release();
        }
    }
   }
   
   public void startWSDMClient(){
       WSDMPerfClient client =  new WSDMPerfClient(serviceUrl,100,1000);
       Thread t = new Thread(client);
       t.setDaemon(true);
       t.start();
   }
   
   
   public void setEndTime(long endTime) {
    this.endTime = endTime;
}

public static void main(String[] args) throws HasthiException {
//    DummyService dummyService = new DummyService();
//    dummyService.start();
//    
//    System.out.println(dummyService.getServiceUrl() + " Started");
    
    final FooDocument fooRequest = FooDocument.Factory.newInstance();
    fooRequest.addNewFoo().setIn("Hello");
    
    
    PerfClient.PerfResponseVerifier perfResponseVerifier = new PerfClient.PerfResponseVerifier() {
        public boolean verify(XmlObject response) {
            String in = ((FooDocument)fooRequest).getFoo().getIn();
            if(response instanceof FooResponseDocument){
                String out = ((FooResponseDocument)response).getFooResponse().getOut();
                return in.equals(out);
            }else{
                System.out.println(XmlBeanUtils.prettyPrint(response));
                return false;
            }
        }
    };
    
    ClientSet clientSet = new ClientSet("test",100,1000,fooRequest,"http://129.79.246.253:5555/dummy",perfResponseVerifier);
    //clientSet.startWSDMClient();
    clientSet.runTests();
}
   
}
